package tech.waterism.utils.method;

import lombok.Data;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import tech.waterism.constant.DispatchConstants;
import tech.waterism.constant.StationTypeConstans;
import tech.waterism.document.DPrincipleCustomDocument;
import tech.waterism.dto.*;
import tech.waterism.entity.DPrinciple;
import tech.waterism.entity.FPInput;
import tech.waterism.utils.ConvertZV;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

@Data
@Component
public class DispatchCalculate {
    @Autowired
    private ResFlood resFlood;

    @Autowired
    private StoreFlood storeFlood;

    @Autowired
    private DPrincipleService dPrincipleService;

    @Autowired
    private DPrincipleCustomService dPrincipleCustomService;

    /**
     * 调度接口--联合调度使用--预报调度专用
     *
     * @param indexObject  调度节点
     * @param topoObjects  拓扑对象/联调对象
     * @param dtOperate    起调时间
     * @param dtModify     修改时间
     * @param dispatchType 水库调洪类型：0为天然流量, 1为当前出流, 2为调度规则 4为自定义规则出流
     */
    public void resFunction(Integer indexObject, List<TopoObjectDto> topoObjects, Date dtOperate, Date dtModify,
                            Integer dispatchType) {
        FPIndexDto fpIndex = topoObjects.get(indexObject).getFpIndex();
        if (fpIndex.getPrincipleId() != null && fpIndex.getPrincipleCustom() == null) {
            DPrincipleCustomDocument principleCustomDocument =
                    dPrincipleCustomService.getById(fpIndex.getPrincipleId());
            if (principleCustomDocument != null) {
                fpIndex.setPrincipleCustom(principleCustomDocument);
            }
        }
        PrincipleData principleData = null;
        DPrinciple dPrinciple = dPrincipleService.getOne(fpIndex.getStcd());
        if (dPrinciple != null) {
            principleData = PrincipleFactory.getPrincipleInstance(dPrinciple.getClassname());
        }
        int timeNumOperate = 0;
        DispatchTempDataDto dispatchTempData = new DispatchTempDataDto();
        for (int time_num = 0; time_num < fpIndex.getData().size(); time_num++) {
            if (fpIndex.getData().get(time_num).getDt().before(dtOperate)) {
                continue;
            }
            if (fpIndex.getData().get(time_num).getDt().equals(dtOperate)) {
                initialResFunction(fpIndex, dtOperate, time_num);
                timeNumOperate = time_num;
                if (dPrinciple != null) {
                    // 初始化调洪参数
                    principleData.initialObject(indexObject, topoObjects, timeNumOperate);
                }
            }
            if (fpIndex.getData().get(time_num).getDt().after(dtOperate) &&
                    fpIndex.getData().get(time_num).getQSim() != null) {
                fpIndex.getData().get(time_num).setQIn(fpIndex.getData().get(time_num).getQSim());
            }
            if (dtModify != null && dtModify.after(dtOperate)) {
                resFlood.makePlanByGivenOutWays(fpIndex, time_num, timeNumOperate);
            } else {
                if (dispatchType == DispatchConstants.DISPATCH_PLAN_TYPE_NATUREINFLOW) {// 按天然出流
                    resFlood.makePlanByGivenInflowToOutflow(fpIndex, time_num, timeNumOperate);
                } else if (dispatchType == DispatchConstants.DISPATCH_PLAN_TYPE_BEGINOUTFLOW) {// 按当前出流
                    resFlood.makePlanByGivenOutflowBegToOutflow(fpIndex, time_num, timeNumOperate);
                } else if (dispatchType == DispatchConstants.DISPATCH_PLAN_TYPE_DISPATCHRULES) {// 按调度规则
                    dispatchTempData =
                            resFlood.makePlanByGivenInflow(dispatchTempData, indexObject, topoObjects, principleData,
                                    time_num, timeNumOperate);
                } else if (dispatchType == DispatchConstants.DISPATCH_PLAN_TYPE_DISPATCHRULES_CUSTOM) {// 按调度规则  custom
                    if (fpIndex.getPrincipleId() != null) {
                        dispatchTempData =
                                resFlood.makePlanByCustomPrinciple(dispatchTempData, fpIndex, time_num, timeNumOperate);
                    } else {
                        resFlood.makePlanByGivenOutflowBegToOutflow(fpIndex, time_num, timeNumOperate);
                    }
                } else {// 默认按当前出流
                    resFlood.makePlanByGivenOutflowBegToOutflow(fpIndex, time_num, timeNumOperate);
                }
            }
        }
    }

    /**
     * 调度接口--单库调度使用--河系预报专用
     *
     * @param fpIndex      调度节点
     * @param dtOperate    起调时间
     * @param dtModify     修改时间
     * @param dispatchType 水库调洪类型：0为天然出流, 1为当前出流, 2为规则出流, 3为反算出流 4为自定义规则出流
     */
    public void resFunction(FPIndexDto fpIndex, Date dtOperate, Date dtModify, Integer dispatchType) {
        int timeNumOperate = 0;
        DispatchTempDataDto dispatchTempData = new DispatchTempDataDto();
        if (fpIndex.getPrincipleId() != null && fpIndex.getPrincipleCustom() == null) {
            DPrincipleCustomDocument principleCustomDocument =
                    dPrincipleCustomService.getById(fpIndex.getPrincipleId());
            if (principleCustomDocument != null) {
                fpIndex.setPrincipleCustom(principleCustomDocument);
            }
        }
        for (int time_num = 0; time_num < fpIndex.getData().size(); time_num++) {
            if (fpIndex.getData().get(time_num).getDt().before(dtOperate)) {
                // 给预热期数据补充v
                if (Objects.nonNull(fpIndex.getData().get(time_num).getRz())) {
                    CurveZVDto zvDto =
                            ConvertZV.getVFromZ(fpIndex.getCurveHs(), fpIndex.getData().get(time_num).getRz());
                    fpIndex.getData().get(time_num).setV(zvDto.getResult());
                }
                continue;
            }
            if (fpIndex.getData().get(time_num).getDt().equals(dtOperate)) {
                initialResFunction(fpIndex, dtOperate, time_num);
                timeNumOperate = time_num;
            }
            if (fpIndex.getData().get(time_num).getDt().after(dtOperate) &&
                    fpIndex.getData().get(time_num).getQSim() != null) {
                fpIndex.getData().get(time_num).setQIn(fpIndex.getData().get(time_num).getQSim());
            }
            if (dtModify != null && dtModify.after(dtOperate)) {
                resFlood.makePlanByGivenOutWays(fpIndex, time_num, timeNumOperate);
            } else {
                if (dispatchType != null) {
                    if (dispatchType == DispatchConstants.DISPATCH_PLAN_TYPE_NATUREINFLOW) {// 按天然出流
                        resFlood.makePlanByGivenInflowToOutflow(fpIndex, time_num, timeNumOperate);
                    } else if (dispatchType == DispatchConstants.DISPATCH_PLAN_TYPE_BEGINOUTFLOW) {// 按当前出流
                        resFlood.makePlanByGivenOutflowBegToOutflow(fpIndex, time_num, timeNumOperate);
                    } else if (dispatchType == DispatchConstants.DISPATCH_PLAN_TYPE_OPTIMIZEDOUTFLOW) {// 按反算出流
                        resFlood.makePlanByGivenInitialValueToOutflow(fpIndex, time_num, timeNumOperate);
                    } else if (dispatchType == DispatchConstants.DISPATCH_PLAN_TYPE_DISPATCHRULES_CUSTOM) {
                        // 按调度规则  custom
                        if (fpIndex.getPrincipleId() != null) {
                            dispatchTempData = resFlood.makePlanByCustomPrinciple(dispatchTempData, fpIndex, time_num,
                                    timeNumOperate);
                        } else {
                            resFlood.makePlanByGivenOutflowBegToOutflow(fpIndex, time_num, timeNumOperate);
                        }
                    } else {
                        resFlood.makePlanByGivenOutflowBegToOutflow(fpIndex, time_num, timeNumOperate);
                    }
                } else {
                    resFlood.makePlanByGivenOutflowBegToOutflow(fpIndex, time_num, timeNumOperate);
                }
            }
        }
    }

    private void initialResFunction(FPIndexDto fpIndex, Date dtOperate, int timeNum) {
        fpIndex.getData().get(timeNum).setGateNote("调洪开始");
        double rzBeg = -1;
        if (fpIndex.getRzBeg() != null) {
            rzBeg = fpIndex.getRzBeg();
            fpIndex.getData().get(timeNum).setRz(fpIndex.getRzBeg());
        } else if (fpIndex.getFloodCharacter() != null && fpIndex.getFloodCharacter().getStRsvrfsrBList() != null &&
                fpIndex.getFloodCharacter().getStRsvrfsrBList().size() > 0) {
            rzBeg = ResFlood.getZNSummer(fpIndex.getFloodCharacter().getStRsvrfsrBList(), dtOperate);
            fpIndex.getData().get(timeNum).setRz(rzBeg);
            fpIndex.setRzBeg(rzBeg);
        }
        if (rzBeg < 0) {
            if (rzBeg < 0 && fpIndex.getCurveHs() != null && fpIndex.getCurveHs().size() > 0) {
                rzBeg = fpIndex.getCurveHs().get(0).getZ();
            }
            fpIndex.getData().get(timeNum).setRz(rzBeg);
            fpIndex.setRzBeg(rzBeg);
        }
        // 补充出流逻辑
        if ((fpIndex.getData().get(timeNum).getQOutIsExist() == null ||
                !fpIndex.getData().get(timeNum).getQOutIsExist()) && fpIndex.getQOutBeg() != null) {
            fpIndex.getData().get(timeNum).setQOut(fpIndex.getQOutBeg());
            fpIndex.getData().get(timeNum).setQOutIsExist(true);
        }
    }

    public void resCheck(List<TopoObjectDto> topoObjects, Date dtOperate) {
        for (int indexObject = 0; indexObject < topoObjects.size(); indexObject++) {
            if (StationTypeConstans.RSVR_SET.contains(topoObjects.get(indexObject).getFpIndex().getOutcd())) {
                DispatchTempDataDto dispatchTempData = new DispatchTempDataDto();
                int timeNumOperate = 0;
                // 调度规则
                PrincipleData principleData = null;
                DPrinciple dPrinciple = dPrincipleService.getOne(topoObjects.get(indexObject).getFpIndex().getStcd());
                if (dPrinciple != null) {
                    principleData = PrincipleFactory.getPrincipleInstance(dPrinciple.getClassname());
                    for (int time_num = 0; time_num < topoObjects.get(indexObject).getFpIndex().getData().size();
                         time_num++) {
                        if (topoObjects.get(indexObject).getFpIndex().getData().get(time_num).getDt()
                                .before(dtOperate)) {
                            continue;
                        }
                        if (topoObjects.get(indexObject).getFpIndex().getData().get(time_num).getDt()
                                .equals(dtOperate)) {
                            timeNumOperate = time_num;
                        }
                        dispatchTempData = resFlood.checkPlanByGivenInflow(dispatchTempData, indexObject, topoObjects,
                                principleData, time_num, timeNumOperate);
                        if (dispatchTempData.getDoNotCheck() != null && dispatchTempData.getDoNotCheck()) {
                            break;
                        }
                    }
                }
            }
        }
    }

    public void storeCheck(List<DispatchObjectDto> dispatchObjects, Date dtOperate) {
        for (DispatchObjectDto dispatchObject : dispatchObjects) {
            List<TopoObjectDto> topoObjects = dispatchObject.getDispatchObject();
            for (int indexObject = 0; indexObject < topoObjects.size(); indexObject++) {
                if ("DZQ".equals(topoObjects.get(indexObject).getFpIndex().getOutcd())) {
                    DispatchTempDataDto dispatchTempData = new DispatchTempDataDto();
                    int timeNumOperate = 0;
                    // 调度规则
                    PrincipleData principleData = null;
                    DPrinciple dPrinciple =
                            dPrincipleService.getOne(topoObjects.get(indexObject).getFpIndex().getStcd());
                    if (dPrinciple != null) {
                        principleData = PrincipleFactory.getPrincipleInstance(dPrinciple.getClassname());
                        for (int time_num = 0; time_num < topoObjects.get(indexObject).getFpIndex().getData().size();
                             time_num++) {
                            if (topoObjects.get(indexObject).getFpIndex().getData().get(time_num).getDt()
                                    .before(dtOperate)) {
                                continue;
                            }
                            if (topoObjects.get(indexObject).getFpIndex().getData().get(time_num).getDt()
                                    .equals(dtOperate)) {
                                timeNumOperate = time_num;
                            }
                            dispatchTempData =
                                    storeFlood.checkPlanByGivenInflow(dispatchTempData, indexObject, topoObjects,
                                            principleData, time_num, timeNumOperate);
                        }
                    }
                }
            }
        }
    }

    /**
     * @param indexObject             调度节点
     * @param indexObjectDown         排洪节点（河道）
     * @param topoObjects             拓扑对象/联调对象
     * @param dtOperate               起调时间
     * @param dtModify                修改时间
     * @param diversionOrDischarge    分洪or排洪
     * @param indexObjectUpReturnList 分洪节点返回列表（记录已更新的节点，作为下次叠加的依据）
     */
    public List<Integer> storeFunction(Integer indexObject, Integer indexObjectDown, List<TopoObjectDto> topoObjects,
                                       Date dtOperate, Date dtModify, int diversionOrDischarge, List<Integer> indexObjectUpReturnList) {
        TopoObjectDto topoObject = topoObjects.get(indexObject);
        PrincipleData principleData = null;
        DPrinciple dPrinciple = dPrincipleService.getOne(topoObject.getFpIndex().getStcd());
        if (dPrinciple != null) {
            principleData = PrincipleFactory.getPrincipleInstance(dPrinciple.getClassname());
        }
        List<Integer> indexObjectUpList = null;
        // 筛选分洪节点（河道）
        if (diversionOrDischarge == DispatchConstants.OPERATE_FLOOD_DIVERSION) {
            indexObjectUpList = new ArrayList<>();
            String stcd = "";
            for (FPInput fpInput : topoObjects.get(indexObject).getFpInputs()) {
                if (fpInput.getPlcd() == null) {
                    stcd = fpInput.getArcd();
                }
            }
            boolean isFirstCircle = true;
            for (int index_object = 0; index_object < topoObjects.size(); index_object++) {
                if (isFirstCircle) {
                    // 直接的分洪节点（河道）
                    if (stcd.equals(topoObjects.get(index_object).getFpIndex().getStcd())) {
                        indexObjectUpList.add(index_object);
                        if (topoObjects.get(index_object).getFpIndex().getPstcd() != null) {
                            stcd = topoObjects.get(index_object).getFpIndex().getPstcd();
                            isFirstCircle = false;
                        }
                    }
                } else {
                    // 分洪节点（河道）相应的虚拟节点
                    if (stcd.equals(topoObjects.get(index_object).getFpIndex().getPstcd())) {
                        indexObjectUpList.add(index_object);
                    }
                }
            }
        }
        int timeNumOperate = 0;
        //        int timeNumModify = 0;
        DispatchTempDataDto dispatchTempData = new DispatchTempDataDto();
        boolean doModify = false;
        for (int time_num = 0; time_num < topoObject.getFpIndex().getData().size(); time_num++) {
            if (topoObject.getFpIndex().getData().get(time_num).getDt().before(dtOperate)) {
                continue;
            }
            if (topoObject.getFpIndex().getData().get(time_num).getDt().equals(dtOperate)) {
                topoObjects.get(indexObject).getFpIndex().getData().get(time_num).setGateNote("调洪开始");
                double rzBeg = -1;
                if (topoObject.getFpIndex().getRzBeg() != null) {
                    topoObjects.get(indexObject).getFpIndex().getData().get(time_num)
                            .setRz(topoObject.getFpIndex().getRzBeg());
                } else if (topoObject.getFpIndex().getFloodCharacter() != null &&
                        topoObject.getFpIndex().getFloodCharacter().getStRsvrfsrBList() != null &&
                        topoObject.getFpIndex().getFloodCharacter().getStRsvrfsrBList().size() > 0) {
                    rzBeg = ResFlood.getZNSummer(topoObject.getFpIndex().getFloodCharacter().getStRsvrfsrBList(),
                            dtOperate);
                    topoObjects.get(indexObject).getFpIndex().getData().get(time_num).setRz(rzBeg);
                    topoObjects.get(indexObject).getFpIndex().setRzBeg(rzBeg);
                }
                if (rzBeg < 0) {
                    if (rzBeg < 0 && topoObject.getFpIndex().getCurveHs() != null &&
                            topoObject.getFpIndex().getCurveHs().size() > 0) {
                        rzBeg = topoObject.getFpIndex().getCurveHs().get(0).getZ();
                    }
                    topoObjects.get(indexObject).getFpIndex().getData().get(time_num).setRz(rzBeg);
                    topoObjects.get(indexObject).getFpIndex().setRzBeg(rzBeg);
                }
                timeNumOperate = time_num;
            }
            if (topoObjects.get(indexObject).getFpIndex().getData().get(time_num).getDt().after(dtOperate)) {
                topoObjects.get(indexObject).getFpIndex().getData().get(time_num)
                        .setQIn(topoObjects.get(indexObject).getFpIndex().getData().get(time_num).getQSim());
            }
            if (dtModify != null && dtModify.after(dtOperate)) {
                doModify = true;
                if (DispatchConstants.STATION_CODE_YUELIANGPAO.equals(
                        (topoObjects.get(indexObject).getFpIndex().getStcd())) ||
                        DispatchConstants.STATION_CODE_YUELIANGPAO.equals(
                                (topoObjects.get(indexObject).getFpIndex().getPstcd()))) {
                    dispatchTempData =
                            makePlanbyGivenGateNum(dispatchTempData, indexObject, indexObjectDown, topoObjects,
                                    principleData, time_num, timeNumOperate, doModify, diversionOrDischarge);
                } else if (DispatchConstants.STATION_CODE_PANGTOUPAO.equals(
                        (topoObjects.get(indexObject).getFpIndex().getStcd())) ||
                        DispatchConstants.STATION_CODE_PANGTOUPAO.equals(
                                (topoObjects.get(indexObject).getFpIndex().getPstcd()))) {
                    dispatchTempData =
                            makePlanbyGivenGateWidth(dispatchTempData, indexObject, indexObjectDown, topoObjects,
                                    principleData, time_num, timeNumOperate, doModify, diversionOrDischarge);
                }
            } else {
                if (DispatchConstants.STATION_CODE_YUELIANGPAO.equals(
                        (topoObjects.get(indexObject).getFpIndex().getStcd())) ||
                        DispatchConstants.STATION_CODE_YUELIANGPAO.equals(
                                (topoObjects.get(indexObject).getFpIndex().getPstcd())) ||
                        DispatchConstants.STATION_CODE_PANGTOUPAO.equals(
                                (topoObjects.get(indexObject).getFpIndex().getStcd())) ||
                        DispatchConstants.STATION_CODE_PANGTOUPAO.equals(
                                (topoObjects.get(indexObject).getFpIndex().getPstcd()))) {
                    dispatchTempData =
                            storeFunctionYueLiangPaoPangTouPao(dispatchTempData, indexObject, indexObjectDown,
                                    topoObjects, principleData, time_num, timeNumOperate, diversionOrDischarge);
                }
            }

            // 为分洪节点（河道）赋值
            if (diversionOrDischarge == DispatchConstants.OPERATE_FLOOD_DIVERSION && indexObjectUpList != null) {
                for (Integer indexObjectUp : indexObjectUpList) {
                    if (!indexObjectUpReturnList.contains(indexObjectUp)) {
                        if (topoObjects.get(indexObjectUp).getFpIndex().getQDvrIsExist() == null ||
                                topoObjects.get(indexObjectUp).getFpIndex().getQDvrIsExist()) {
                            topoObjects.get(indexObjectUp).getFpIndex().setQDvrIsExist(true);
                        }
                        topoObjects.get(indexObjectUp).getFpIndex().getData().get(time_num)
                                .setQDvr(topoObjects.get(indexObject).getFpIndex().getData().get(time_num).getQDvr());
                        if (time_num == topoObject.getFpIndex().getData().size() - 1) {
                            indexObjectUpReturnList.add(indexObjectUp);
                        }
                    } else {
                        if (topoObjects.get(indexObjectUp).getFpIndex().getData().get(time_num).getQDvr() != null) {
                            topoObjects.get(indexObjectUp).getFpIndex().getData().get(time_num).setQDvr(
                                    topoObjects.get(indexObjectUp).getFpIndex().getData().get(time_num).getQDvr() +
                                            (topoObjects.get(indexObject).getFpIndex().getData().get(time_num)
                                                    .getQDvr() != null ? topoObjects.get(indexObject).getFpIndex()
                                                    .getData().get(time_num).getQDvr() : 0));
                        } else {
                            topoObjects.get(indexObjectUp).getFpIndex().getData().get(time_num).setQDvr(
                                    topoObjects.get(indexObject).getFpIndex().getData().get(time_num).getQDvr());
                        }
                    }
                }
            }
            // 为排洪节点（河道）赋值
            if (diversionOrDischarge == DispatchConstants.OPERATE_FLOOD_DISCHARGE) {
                if (topoObjects.get(indexObjectDown).getFpIndex().getQDscIsExist() == null ||
                        topoObjects.get(indexObjectDown).getFpIndex().getQDscIsExist()) {
                    topoObjects.get(indexObjectDown).getFpIndex().setQDscIsExist(true);
                }
                topoObjects.get(indexObjectDown).getFpIndex().getData().get(time_num)
                        .setQDsc(topoObjects.get(indexObject).getFpIndex().getData().get(time_num).getQDsc());
            }
        }
        return indexObjectUpReturnList;
    }

    /**
     * 蓄滞洪区调度计算(月亮泡 胖头泡定制)
     *
     * @param indexObject          在调的调度对象序号
     * @param indexObjectDown      蓄滞洪区出口的调度对象序号
     * @param timeNum              时间序号
     * @param topoObjects          所有的调度对象属性信息
     * @param diversionOrDischarge 分洪or排洪
     */
    private DispatchTempDataDto storeFunctionYueLiangPaoPangTouPao(DispatchTempDataDto dispatchTempData,
                                                                   Integer indexObject, Integer indexObjectDown, List<TopoObjectDto> topoObjects, PrincipleData principleData,
                                                                   int timeNum, int timeNumOperate, int diversionOrDischarge) {
        int indexObjectYueLiangPao = dispatchTempData.getIndexObjectYueLiangPao();
        int indexObjectPangTouPao = dispatchTempData.getIndexObjectPangTouPao();
        // 得到水位库容关系和特征水位以及泄流设备的属性
        boolean useTwo = true;
        if (timeNum == timeNumOperate) {
            for (int index_object = 0; index_object < topoObjects.size(); index_object++) {
                if ((DispatchConstants.STATION_CODE_YUELIANGPAO.equals(
                        (topoObjects.get(index_object).getFpIndex().getStcd())) ||
                        DispatchConstants.STATION_CODE_YUELIANGPAO.equals(
                                (topoObjects.get(index_object).getFpIndex().getPstcd()))) &&
                        (topoObjects.get(index_object).getFpIndex().getIsUseStore() == null ||
                                !topoObjects.get(index_object).getFpIndex().getIsUseStore())) {
                    dispatchTempData.setIndexObjectYueLiangPao(index_object);
                    indexObjectYueLiangPao = index_object;
                    useTwo = false;
                }
                if ((DispatchConstants.STATION_CODE_PANGTOUPAO.equals(
                        (topoObjects.get(index_object).getFpIndex().getStcd())) ||
                        DispatchConstants.STATION_CODE_PANGTOUPAO.equals(
                                (topoObjects.get(index_object).getFpIndex().getPstcd()))) &&
                        (topoObjects.get(index_object).getFpIndex().getIsUseStore() == null ||
                                !topoObjects.get(index_object).getFpIndex().getIsUseStore())) {
                    dispatchTempData.setIndexObjectPangTouPao(index_object);
                    indexObjectPangTouPao = index_object;
                    useTwo = false;
                }
            }
            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setGateNote("蓄洪开始");
        }
        // 排洪口行洪赋值
        if (indexObjectDown != null) {
            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                    .setQDown(topoObjects.get(indexObjectDown).getFpIndex().getData().get(timeNum).getQSim());
        }
        // 两个都是用且当前的是月亮泡
        boolean isUse = true;
        if (useTwo && (DispatchConstants.STATION_CODE_YUELIANGPAO.equals(
                (topoObjects.get(indexObject).getFpIndex().getStcd())) ||
                DispatchConstants.STATION_CODE_YUELIANGPAO.equals(
                        (topoObjects.get(indexObject).getFpIndex().getPstcd())))) {
            //胖头泡小于自身的容量
            if (topoObjects.get(indexObjectPangTouPao).getFpIndex().getData().get(timeNum).getV() == null ||
                    topoObjects.get(indexObjectPangTouPao).getFpIndex().getData().get(timeNum).getV() <=
                            4245 * 1000000L) {
                isUse = false;
            }
        }
        if (isUse) {
            storeFlood.makePlanByGivenInflow(dispatchTempData, indexObject, topoObjects, principleData, timeNum,
                    timeNumOperate, diversionOrDischarge);
        } else {
            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                    .setFlowWay(DispatchConstants.FLOW_WAY_DOUBLE_GATE_BY_RUNGEKUTTA);
            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setGateNote("");
            if (topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).getNUsedGates() == null) {
                // 设置初始的口门开启个数
                Integer[][] nUsedGates = new Integer[topoObjects.get(indexObject).getFpIndex().getSpillways().size()][];
                for (int j = 0; j < topoObjects.get(indexObject).getFpIndex().getSpillways().size(); j++) {
                    int statusSize = topoObjects.get(indexObject).getFpIndex().getSpillways().get(j).getNopenstates();
                    nUsedGates[j] = new Integer[statusSize];
                    for (int k = 0; k < statusSize; k++) {
                        nUsedGates[j][k] = 0;
                    }
                }
                topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setNUsedGates(nUsedGates);
            }
            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDvr(0.0);
            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setQDsc(0.0);
            storeFlood.resRoutingOnePeriod(timeNum, topoObjects.get(indexObject));// 仅需要进行平衡计算
        }
        return dispatchTempData;
    }

    /**
     * 根据闸门宽度编制调度方案（蓄滞洪区）
     *
     * @param indexObject          在调的调度单元序号
     * @param indexObjectDown      蓄滞洪区出口的调度对象序号
     * @param timeNum              时间序号
     * @param topoObjects          所有的调度单元属性信息
     * @param doModify             修改的时间序号
     * @param diversionOrDischarge 分洪or排洪
     */
    private DispatchTempDataDto makePlanbyGivenGateWidth(DispatchTempDataDto dispatchTempData, Integer indexObject,
                                                         Integer indexObjectDown, List<TopoObjectDto> topoObjects, PrincipleData principleData, int timeNum,
                                                         int timeNumOperate, boolean doModify, int diversionOrDischarge) {
        // 得到水位库容关系和特征水位以及泄流设备的属性
        if (timeNum == timeNumOperate) {
            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setGateNote("蓄洪开始");
        }
        // 排洪口行洪赋值
        if (indexObjectDown != null) {
            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                    .setQDown(topoObjects.get(indexObjectDown).getFpIndex().getData().get(timeNum).getQSim());
        }
        if (doModify) {
            dispatchTempData =
                    storeFlood.makePlanbyGivenGateWidth(dispatchTempData, indexObject, topoObjects, principleData,
                            timeNum, timeNumOperate, diversionOrDischarge);
        } else {
            dispatchTempData =
                    storeFlood.makePlanByGivenInflow(dispatchTempData, indexObject, topoObjects, principleData, timeNum,
                            timeNumOperate, diversionOrDischarge);
        }
        return dispatchTempData;
    }

    /**
     * 根据给定闸门开启数量编制调度方案（蓄滞洪区）
     *
     * @param indexObject          在调的调度单元序号
     * @param indexObjectDown      蓄滞洪区出口的调度对象序号
     * @param timeNum              时间序号
     * @param topoObjects          所有的调度单元属性信息
     * @param diversionOrDischarge 分洪or排洪
     */
    private DispatchTempDataDto makePlanbyGivenGateNum(DispatchTempDataDto dispatchTempData, Integer indexObject,
                                                       Integer indexObjectDown, List<TopoObjectDto> topoObjects, PrincipleData principleData, int timeNum,
                                                       int timeNumOperate, boolean doModify, int diversionOrDischarge) {
        // 得到水位库容关系和特征水位以及泄流设备的属性
        if (timeNum == timeNumOperate) {
            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum).setGateNote("蓄洪开始");
        }
        // 排洪口行洪赋值
        if (indexObjectDown != null) {
            topoObjects.get(indexObject).getFpIndex().getData().get(timeNum)
                    .setQDown(topoObjects.get(indexObjectDown).getFpIndex().getData().get(timeNum).getQSim());
        }
        if (doModify) {
            dispatchTempData =
                    storeFlood.makePlanbyGivenGateNum(dispatchTempData, indexObject, topoObjects, principleData,
                            timeNum, timeNumOperate, diversionOrDischarge);
        } else {
            dispatchTempData =
                    storeFlood.makePlanByGivenInflow(dispatchTempData, indexObject, topoObjects, principleData, timeNum,
                            timeNumOperate, diversionOrDischarge);
        }
        return dispatchTempData;
    }
}
